#include <iostream>
#include <thread>
using namespace std;

void myprint()
{
    cout<<"sub thread start"<<endl;
    
    cout<<"sub thread end"<<endl;
}
class SubThread
{
    public :
    int & m_i;
    SubThread(int & i):m_i(i) 
    {
        cout<<"构造函数"<<endl;
    }

    SubThread(const SubThread & sub):m_i(sub.m_i)
    {
        cout<<"拷贝构造函数"<<endl;
    }
    void operator() () // 不可以带参数
    {
        cout<<"sub2 thread start"<<endl;
        cout<<"m_i 值为:"<<m_i<<endl;
        cout<<"sub2 thread end"<<endl;
    }
    ~SubThread()
    {
        cout<<"destory"<<endl;
    }
};
int main()
{
    /*线程需要从 函数 function 开始执行
        若主线程先于子线程执行完毕，则子线程通常会被强行终止
    */
    /*
        thread  标准库的类
        参数 ： 可调用对象(函数 , 对象，lambda 表达式)

        join() :阻塞主线程，让主线程等待子线程执行完毕，然后子线程和主线程汇合，然后主线程再执行

        detach() : 主线程不和子线程汇合，主线程执行结束后 并不影响子线程的执行
        与这个主线程 关联的 thread对象就会失去主线程的关联，子线程驻留在后台运行
        相当于被 C++ 运行时刻接管，当 这个子线程执行完成，当这个子线程执行完成后,
        由后台进行回收

        joinable() : 判断 是否可以使用 join() 的; 一旦调用 detach()/join() 就不能使用 join()
    */
    thread t1(myprint);
    cout<< "Main Thread "<<endl; //主线程
    cout<<t1.joinable()<<endl;
    t1.join();  //阻塞主线程，等待 t1 执行完成


    //类 可调用对象
    //对象被复制到线程中去，执行完主线程后，sub会被销毁，但被复制的对象 仍然存在

    int i = 5;
    SubThread sub(i);
    thread t2(sub);
    t2.detach(); ////阻塞主线程，等待 t2 执行完成
    cout<< "Main Thread "<<endl; //主线程
    cout<< "Main Thread "<<endl; //主线程
    cout<< "Main Thread "<<endl; //主线程
    cout<< "Main Thread "<<endl; //主线程
    cout<< "Main Thread "<<endl; //主线程
    cout<< "Main Thread "<<endl; //主线程
    cout<< "Main Thread "<<endl; //主线程

    ////////////
    // lambda 表达式
    auto mylambda = []{
        cout<<"Thread 3 start"<<endl;
        cout<<"Thread 3 end"<<endl;
    };
    thread t3(mylambda);
    t3.join();
    return 0;
}